package com.loukou.lkt.lkt.service.impl;

import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import com.google.common.base.Strings;
import com.loukou.lkt.lkt.bo.PageList;
import com.loukou.lkt.lkt.bo.Query;
import com.loukou.lkt.lkt.bo.SupplierBo;
import com.loukou.lkt.lkt.bo.SupplierExportCsvBean;
import com.loukou.lkt.lkt.dao.OrderOperateLogDao;
import com.loukou.lkt.lkt.dao.SupplierDao;
import com.loukou.lkt.lkt.entity.OrderOperateLog;
import com.loukou.lkt.lkt.entity.Supplier;
import com.loukou.lkt.lkt.enums.InvoiceTypeEnum;
import com.loukou.lkt.lkt.enums.OrderOperateLogTypeEnum;
import com.loukou.lkt.lkt.enums.SettlementTypeEnum;
import com.loukou.lkt.lkt.enums.SupplierIsExamineEnum;
import com.loukou.lkt.lkt.enums.SupplierIsInUseEnum;
import com.loukou.lkt.lkt.enums.SupplierTypeEnum;
import com.loukou.lkt.lkt.resp.RespDto;
import com.loukou.lkt.lkt.service.SupplierService;

@Service
public class SupplierServiceImpl implements SupplierService {

	@Autowired
	private SupplierDao supplierDao;
	
	@Autowired
	private OrderOperateLogDao orderOperateLogDao;

	@Override
	public RespDto<PageList<SupplierBo>> getList(final String supplierCode, final String supplierName,
			final int settmentType, final int isExamine, final int isUse, final int pageIndex, final int pageSize) {
		RespDto<PageList<SupplierBo>> resp = new RespDto<PageList<SupplierBo>>();
		Sort sort = new Sort(Direction.DESC, "createTime");
		Page<Supplier> pageDtos = supplierDao.findAll(new Specification<Supplier>() {
			@Override
			public Predicate toPredicate(Root<Supplier> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				Query<Supplier> q = new Query<Supplier>(cb, root, query);
				q.like("supplierCode", supplierCode);
				q.like("supplierName", supplierName);
				if (settmentType > -1) {
					q.eq("settmentType", settmentType);
				}
				if (isUse > -1) {
					q.eq("isUse", isUse);
				}
				if (isExamine > -1) {
					q.eq("isExamine", isExamine);
				}

				return q.toPredicate();
			}
		}, new PageRequest(pageIndex - 1, pageSize, sort));

		PageList<SupplierBo> pageList = new PageList<SupplierBo>();
		List<SupplierBo> supplierBoList = new ArrayList<SupplierBo>();
		SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
		for (Supplier s : pageDtos.getContent()) {
			SupplierBo supplierBo = new SupplierBo();
			BeanUtils.copyProperties(s, supplierBo);
			supplierBo.setSettmentTypeStr(SettlementTypeEnum.parseSettlementTypeEnum(s.getSettmentType()).getName());
			supplierBo.setSupplierTypeStr(SupplierTypeEnum.parseSupplierTypeEnum(s.getSupplierType()).getName());
			supplierBo.setInvoiceTypeStr(InvoiceTypeEnum.parseInvoiceTypeEnum(s.getInvoiceType()).getName());
			supplierBo.setIsExamineStr(SupplierIsExamineEnum.parseEnum(s.getIsUse()).getComment());
			supplierBo.setIsUseStr(SupplierIsInUseEnum.parseEnum(s.getIsUse()).getComment());
			if (s.getContractStartTime() != null) {
				supplierBo.setContractStartTime(sf.format(s.getContractStartTime()));
			}
			if (s.getContractEndTime() != null) {
				supplierBo.setContractEndTime(sf.format(s.getContractEndTime()));
			}

			supplierBoList.add(supplierBo);
		}
		pageList.setEntityList(supplierBoList);
		pageList.setCurPageIndex(pageIndex);
		pageList.setPageCount(pageDtos.getTotalPages());
		pageList.setRecordCount(pageDtos.getTotalElements());
		resp.setResult(pageList);
		return resp;
	}

	@Override
	public Page<Supplier> getUsndDitList(final String supplierCode, final String supplierName, final int pageIndex,
			final int pageSize) {
		Page<Supplier> pageDtos = supplierDao.findAll(new Specification<Supplier>() {
			@Override
			public Predicate toPredicate(Root<Supplier> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				Query<Supplier> q = new Query<Supplier>(cb, root, query);
				q.like("supplierCode", supplierCode);
				q.like("supplierName", supplierName);
				q.eq("isUse", SupplierIsInUseEnum.TYPE_YES.getType());
				q.eq("isExamine", SupplierIsExamineEnum.TYPE_YES.getType());

				return q.toPredicate();
			}
		}, new PageRequest(pageIndex - 1, pageSize));
		return pageDtos;
	}

	@Override
	public SupplierBo getDetail(int id) {
		SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
		Supplier supplier = supplierDao.findOne(id);
		SupplierBo supplierBo = new SupplierBo();
		BeanUtils.copyProperties(supplier, supplierBo);
		if (supplier.getDeposit() == null)
			supplierBo.setDeposit("");
		else {
			DecimalFormat df = new DecimalFormat("0.00");
			if (df.format(supplier.getDeposit()).length() == 11) {
				df = new DecimalFormat("0.0");
			}
			if (df.format(supplier.getDeposit()).length() >= 12) {
				df = new DecimalFormat("0");
			}
			supplierBo.setDeposit(df.format(supplier.getDeposit()));
		}
		supplierBo.setSettmentTypeStr(SettlementTypeEnum.parseSettlementTypeEnum(supplier.getSettmentType()).getName());
		supplierBo.setSupplierTypeStr(SupplierTypeEnum.parseSupplierTypeEnum(supplier.getSupplierType()).getName());
		supplierBo.setInvoiceTypeStr(InvoiceTypeEnum.parseInvoiceTypeEnum(supplier.getInvoiceType()).getName());
		supplierBo.setIsExamineStr(SupplierIsExamineEnum.parseEnum(supplier.getIsUse()).getComment());
		supplierBo.setIsUseStr(SupplierIsInUseEnum.parseEnum(supplier.getIsUse()).getComment());
		if (supplier.getContractStartTime() != null) {
			supplierBo.setContractStartTime(sf.format(supplier.getContractStartTime()));
		}
		if (supplier.getContractEndTime() != null) {
			supplierBo.setContractEndTime(sf.format(supplier.getContractEndTime()));
		}
		return supplierBo;
	}

	@Override
	public RespDto<SupplierBo> save(SupplierBo supplierBo) {
		RespDto<SupplierBo> res = new RespDto<SupplierBo>();
		// --必填项判断
		if (Strings.isNullOrEmpty(supplierBo.getSupplierCode())
				|| Strings.isNullOrEmpty(supplierBo.getBeneficiaryName())
				|| Strings.isNullOrEmpty(supplierBo.getSupplierName())
				|| Strings.isNullOrEmpty(supplierBo.getManagePerson())
				|| Strings.isNullOrEmpty(supplierBo.getContractMobile())
				|| Strings.isNullOrEmpty(supplierBo.getContractPerson()) || supplierBo.getSettmentType() < 0) {
			res.setCode(301);
			res.setMsg("请填写必填项");
			return res;
		}

		// --编号重复

		// --编辑
		SimpleDateFormat sf = new SimpleDateFormat("yyyy-mm-dd");
		if (supplierBo.getId() > 0) {
			Supplier supplier = supplierDao.findOne(supplierBo.getId());
			if (supplier == null) {
				res.setCode(302);
				res.setMsg("获取信息失败");
				return res;
			}
			BeanUtils.copyProperties(supplierBo, supplier);
			if (Strings.isNullOrEmpty(supplierBo.getDeposit()))
				supplier.setDeposit(null);
			else
				supplier.setDeposit(Double.parseDouble(supplierBo.getDeposit()));

			try {
				if (!Strings.isNullOrEmpty(supplierBo.getContractStartTime()))
					supplier.setContractStartTime(sf.parse(supplierBo.getContractStartTime()));
				else
					supplier.setContractStartTime(null);
				if (!Strings.isNullOrEmpty(supplierBo.getContractEndTime()))
					supplier.setContractEndTime(sf.parse(supplierBo.getContractEndTime()));
				else
					supplier.setContractEndTime(null);
			} catch (Exception e) {
				e.printStackTrace();
			}
			supplierDao.save(supplier);
		}

		// --新增
		else {
			if (supplierDao.findBySupplierCode(supplierBo.getSupplierCode()) != null) {
				res.setCode(303);
				res.setMsg("编号重复");
				return res;
			}
			Supplier newSupplier = new Supplier();
			BeanUtils.copyProperties(supplierBo, newSupplier);
			if (Strings.isNullOrEmpty(supplierBo.getDeposit()))
				newSupplier.setDeposit(null);
			else
				newSupplier.setDeposit(Double.valueOf(supplierBo.getDeposit()));
			try {
				if (!Strings.isNullOrEmpty(supplierBo.getContractStartTime()))
					newSupplier.setContractStartTime(sf.parse(supplierBo.getContractStartTime()));
				else
					newSupplier.setContractStartTime(null);
				if (!Strings.isNullOrEmpty(supplierBo.getContractEndTime()))
					newSupplier.setContractEndTime(sf.parse(supplierBo.getContractEndTime()));
				else
					newSupplier.setContractEndTime(null);
			} catch (Exception e) {
				e.printStackTrace();
			}
			supplierDao.save(newSupplier);
		}

		return res;

	}

	@Override
	public RespDto<List<Supplier>> getByIsUseAndIsExamineAndIds(int isUse, int isExamine, List<Integer> ids) {

		if (isUse < 0 || isExamine < 0) {
			return new RespDto<List<Supplier>>(401, "参数有误");
		}
		RespDto<List<Supplier>> resp = new RespDto<List<Supplier>>(200, "");
		// Sort sort = new Sort(Direction.DESC, "id");
		// Pageable pageable = new PageRequest(pageNum - 1, pageSize, sort);
		if (CollectionUtils.isEmpty(ids)) {
			return new RespDto<List<Supplier>>(400, "结果为空");
		}
		List<Supplier> result = supplierDao.findByIsUseAndIsExamineAndIdIn(isUse, isExamine, ids);
		if (CollectionUtils.isEmpty(result)) {
			resp.setCode(400);
			resp.setMsg("结果为空");
			return resp;
		}
		resp.setResult(result);
		return resp;
	}

	@Override
	public RespDto<List<Supplier>> getBySupplierName(String supplierName, int isUse, int isExamine) {

		if (StringUtils.isBlank(supplierName) || isUse < 0 || isExamine < 0) {
			return new RespDto<List<Supplier>>(401, "参数有误");
		}

		RespDto<List<Supplier>> resp = new RespDto<List<Supplier>>(200, "");
		List<Supplier> result = supplierDao.findByIsUseAndIsExamineAndSupplierNameLike(supplierName, isUse, isExamine);
		if (CollectionUtils.isEmpty(result)) {
			resp.setCode(400);
			resp.setMsg("结果为空");
			return resp;
		}
		resp.setResult(result);
		return resp;
	}

	@Override
	public RespDto<List<Supplier>> getBySupplierCode(String supplierCode, int isUse, int isExamine) {

		if (StringUtils.isBlank(supplierCode) || isUse < 0 || isExamine < 0) {
			return new RespDto<List<Supplier>>(401, "参数有误");
		}
		RespDto<List<Supplier>> resp = new RespDto<List<Supplier>>(200, "");
		// Sort sort = new Sort(Direction.DESC, "id");
		// Pageable pageable = new PageRequest(pageNum - 1, pageSize, sort);
		List<Supplier> result = supplierDao.findByIsUseAndIsExamineAndSupplierCode(isUse, isExamine, supplierCode);

		if (CollectionUtils.isEmpty(result)) {
			resp.setCode(400);
			resp.setMsg("结果为空");
			return resp;
		}
		resp.setResult(result);
		return resp;
	}

	@Override
	public RespDto<List<Supplier>> getBySupplierIds(List<Integer> supplierIds) {

		if (CollectionUtils.isEmpty(supplierIds)) {
			return new RespDto<List<Supplier>>(400, "supplierIds is empty");
		}
		RespDto<List<Supplier>> resp = new RespDto<List<Supplier>>(200, "");

		List<Supplier> result = (List<Supplier>) supplierDao.findAll(supplierIds);
		if (CollectionUtils.isEmpty(result)) {
			resp.setCode(400);
			resp.setMsg("结果为空");
			return resp;
		}
		resp.setResult(result);
		return resp;
	}

	@Override
	public RespDto<Integer> updateIsUse(int id, int IsUse) {
		Supplier supplier = supplierDao.findOne(id);
		if (supplier.getIsUse() != IsUse)
			supplier.setIsUse(IsUse);
		supplierDao.save(supplier);
		return new RespDto<Integer>();
	}

	@Override
	public List<SupplierExportCsvBean> exportSupplierList(final String supplierCode, final String supplierName,
			final int settmentType, final int isUse) {

		List<Supplier> supplierList = supplierDao.findAll(new Specification<Supplier>() {
			@Override
			public Predicate toPredicate(Root<Supplier> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				Query<Supplier> q = new Query<Supplier>(cb, root, query);
				q.like("supplierCode", supplierCode);
				q.like("supplierName", supplierName);
				if (isUse >= 0)
					q.eq("isUse", isUse);
				if (settmentType > -1) {
					q.eq("settmentType", settmentType);
				}
				return q.toPredicate();
			}
		});
		List<SupplierExportCsvBean> supplierCsvList = new ArrayList<SupplierExportCsvBean>();
		SimpleDateFormat sf = new SimpleDateFormat("yyyy-mm-dd");
		for (Supplier s : supplierList) {
			if (s == null)
				continue;
			SupplierExportCsvBean secb = new SupplierExportCsvBean();
			// BeanUtils.copyProperties(s, secb);
			secb.setSupplierCode("'" + s.getSupplierCode());
			secb.setDeposit("'" + String.valueOf(s.getDeposit()));
			secb.setSupplierName(s.getSupplierName());
			secb.setBankAccount("'" + s.getBankAccount());
			secb.setBeneficiaryName(s.getBeneficiaryName());
			secb.setGoodsClass(s.getGoodsClass());
			secb.setOpenAccount(s.getOpenAccount());
			secb.setIsUse(SupplierIsInUseEnum.parseEnum(s.getIsUse()).getComment());
			if (s.getSupplierType() == 0) {
				secb.setSupplierType("");
			} else {
				secb.setSupplierType(SupplierTypeEnum.parseSupplierTypeEnum(s.getSupplierType()).getName());
			}
			secb.setInvoiceType(SupplierTypeEnum.parseSupplierTypeEnum(s.getInvoiceType()).getName());
			secb.setSettmentType(SettlementTypeEnum.parseSettlementTypeEnum(s.getSettmentType()).getName());
			if (s.getContractStartTime() != null)
				secb.setContractStartTime(sf.format(s.getContractStartTime()));
			if (s.getContractEndTime() != null)
				secb.setContractEndTime(sf.format(s.getContractEndTime()));
			supplierCsvList.add(secb);
		}
		return supplierCsvList;
	}

	public void saveLog(
			OrderOperateLogTypeEnum actionEnum, String orderCode, int userId,
			String userName, String realName,String actionStr) {
		OrderOperateLog operateLog = new OrderOperateLog();
		operateLog.setActionType(actionEnum.getType());
		operateLog.setAction(actionStr);
		operateLog.setOrderCode(orderCode);
		operateLog.setUserId(userId);
		operateLog.setUserName(userName);
		operateLog.setRealName(realName);
		orderOperateLogDao.save(operateLog);
		
	}
}